Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@apimatic/json-bigint

Package Overview
Dependencies
Maintainers
3
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@apimatic/json-bigint

JSON.parse with bigints support

  • 1.2.0
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
23K
decreased by-7.99%
Maintainers
3
Weekly downloads
 
Created
Source

@apimatic/json-bigint

Build Status

JSON.parse/stringify with bigints support. Based on Douglas Crockford JSON.js package. This is a fork of json-bigint. This module does not have the support for bignumber.js and thus has that dependeny removed.

Install the library using npm:

$ npm install @apimatic/json-bigint

While most JSON parsers assume numeric values have same precision restrictions as IEEE 754 double, JSON specification does not say anything about number precision. Any floating point number in decimal (optionally scientific) notation is valid JSON value. It's a good idea to serialize values which might fall out of IEEE 754 integer precision as strings in your JSON api, but { "value" : 9223372036854775807}, for example, is still a valid RFC4627 JSON string, and in most JS runtimes the result of JSON.parse is this object: { value: 9223372036854776000 }

==========

example:

var JSONbig = require('@apimatic/json-bigint');

var json = '{ "value" : 9223372036854775807, "v2": 123 }';
console.log('Input:', json);
console.log('');

console.log('node.js built-in JSON:');
var r = JSON.parse(json);
console.log('JSON.parse(input).value : ', r.value.toString());
console.log('JSON.stringify(JSON.parse(input)):', JSON.stringify(r));

console.log('\n\nbigint JSON:');
var r1 = JSONbig.parse(json);
console.log('JSONbig.parse(input).value : ', r1.value.toString());
console.log('JSONbig.stringify(JSONbig.parse(input)):', JSONbig.stringify(r1));

Output:

Input: { "value" : 9223372036854775807, "v2": 123 }

node.js built-in JSON:
JSON.parse(input).value :  9223372036854776000
JSON.stringify(JSON.parse(input)): {"value":9223372036854776000,"v2":123}


bigint JSON:
JSONbig.parse(input).value :  9223372036854775807
JSONbig.stringify(JSONbig.parse(input)): {"value":9223372036854775807,"v2":123}

Options

The behaviour of the parser is somewhat configurable through 'options'

options.strict, boolean, default false

Specifies the parsing should be "strict" towards reporting duplicate-keys in the parsed string. The default follows what is allowed in standard json and resembles the behavior of JSON.parse, but overwrites any previous values with the last one assigned to the duplicate-key.

Setting options.strict = true will fail-fast on such duplicate-key occurances and thus warn you upfront of possible lost information.

example:

var JSONbig = require('@apimatic/json-bigint');
var JSONstrict = require('@apimatic/json-bigint')({ strict: true });

var dupkeys = '{ "dupkey": "value 1", "dupkey": "value 2"}';
console.log('\n\nDuplicate Key test with both lenient and strict JSON parsing');
console.log('Input:', dupkeys);
var works = JSONbig.parse(dupkeys);
console.log('JSON.parse(dupkeys).dupkey: %s', works.dupkey);
var fails = 'will stay like this';
try {
  fails = JSONstrict.parse(dupkeys);
  console.log('ERROR!! Should never get here');
} catch (e) {
  console.log(
    'Succesfully catched expected exception on duplicate keys: %j',
    e
  );
}

Output

Duplicate Key test with big number JSON
Input: { "dupkey": "value 1", "dupkey": "value 2"}
JSON.parse(dupkeys).dupkey: value 2
Succesfully catched expected exception on duplicate keys: {"name":"SyntaxError","message":"Duplicate key \"dupkey\"","at":33,"text":"{ \"dupkey\": \"value 1\", \"dupkey\": \"value 2\"}"}

options.storeAsString, boolean, default false

Specifies if BigInts should be stored in the object as a string.

Note that this is a dangerous behavior as it breaks the default functionality of being able to convert back-and-forth without data type changes (as this will convert all BigInts to be-and-stay strings).

example:

var JSONbig = require('@apimatic/json-bigintt');
var JSONbigString = require('@apimatic/json-bigint')({ storeAsString: true });
var key = '{ "key": 1234567890123456789 }';
console.log('\n\nStoring the BigInt as a string, instead of a BigInt');
console.log('Input:', key);
var withInt = JSONbig.parse(key);
var withString = JSONbigString.parse(key);
console.log(
  'Default type: %s, With option type: %s',
  typeof withInt.key,
  typeof withString.key
);

Output

Storing the BigInt as a string, instead of a BigInt
Input: { "key": 1234567890123456789 }
Default type: bigint, With option type: string

options.alwaysParseAsBig, boolean, default false

Specifies if all numbers should be stored as BigInt.

Note that this is a dangerous behavior as it breaks the default functionality of being able to convert back-and-forth without data type changes (as this will convert all Number to be-and-stay BigInt)

example:

var JSONbig = require('@apimatic/json-bigint');
var JSONbigAlways = require('@apimatic/json-bigint')({ alwaysParseAsBig: true });
var key = '{ "key": 123 }'; // there is no need for BigInt by default, but we're forcing it
console.log(`\n\nStoring the Number as a BigInt, instead of a Number`);
console.log('Input:', key);
var normal = JSONbig.parse(key);
var always = JSONbigAlways.parse(key);
console.log(
  'Default type: %s, With option type: %s',
  typeof normal.key,
  typeof always.key
);

Output

Storing the Number as a BigInt, instead of a Number
Input: { "key": 123 }
Default type: number, With option type: bigint

options.protoAction, boolean, default: "error". Possible values: "error", "ignore", "preserve"
options.constructorAction, boolean, default: "error". Possible values: "error", "ignore", "preserve"

Controls how __proto__ and constructor properties are treated. If set to "error" they are not allowed and parse() call will throw an error. If set to "ignore" the prroperty and it;s value is skipped from parsing and object building. If set to "preserve" the __proto__ property is set. One should be extra careful and make sure any other library consuming generated data is not vulnerable to prototype poisoning attacks.

example:

var JSONbigAlways = require('@apimatic/json-bigint')({ protoAction: 'ignore' });
const user = JSONbig.parse('{ "__proto__": { "admin": true }, "id": 12345 }');
// => result is { id: 12345 }

Note on native BigInt support

Stringifying

Full support out-of-the-box, stringifies BigInts as pure numbers (no quotes, no n)

Limitations
  • Roundtrip operations

s === JSONbig.stringify(JSONbig.parse(s)) but

o !== JSONbig.parse(JSONbig.stringify(o))

when o has a value with something like 123n.

JSONbig stringify 123n as 123, which becomes number (aka 123 not 123n) by default when being reparsed.

There is currently no consistent way to deal with this issue, so we decided to leave it, handling this specific case is then up to users.

Keywords

FAQs

Package last updated on 14 Mar 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc